package kz.simplex.photobox.action;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Calendar;

import javax.ejb.Remove;
import javax.ejb.Stateful;
import javax.persistence.EntityExistsException;
import javax.persistence.EntityManager;

import kz.simplex.photobox.model.Role;
import kz.simplex.photobox.model.Status;
import kz.simplex.photobox.model.User;
import kz.simplex.photobox.util.HashUtils;

import org.hibernate.validator.InvalidStateException;
import org.hibernate.validator.InvalidValue;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.faces.FacesMessages;
import org.jboss.seam.log.Log;
import org.jboss.seam.ScopeType;


@Stateful
@Scope(ScopeType.CONVERSATION)
@Name("registerAction")
public class RegisterAction implements Register {
        
    @In
    EntityManager entityManager;
    
    @Logger
    private Log log;
    
    @Out(required = false)
    private User newUser;
    
    @In(required = false)
    private File avatarData;
    
    private String password;
    private String confirm;    
    private boolean conversationStarted = false;
    
    public void newRegistration() {
    	if (newUser == null) {
    		newUser = new User();
    	}
    }
    
    public String startConversation() {
    	newRegistration();
    	setConversationStarted(true);
    	return "";
    }
        
    public String register() {
    	if (!getPassword().equals(getConfirm())) {
    		FacesMessages.instance().addToControl("confirm", "Passwords do not match");
    		return "failed";
    	}
    	if (entityManager.createQuery("from User where username = :username").setParameter("username", newUser.getUsername()).getResultList().size() > 0) {
    		FacesMessages.instance().addToControl("username", "That username is already taken, please choose a different one");
    		return "failed";
    	}
    	
    	Role role = (Role)entityManager.createQuery("from Role where title = :title").setParameter("title", "user").getSingleResult();
    	Status status = (Status)entityManager.createQuery("from Status where status = :status").setParameter("status", "active").getSingleResult();
    	
    	newUser.setRole(role);
    	newUser.setStatus(status);
    	newUser.setLastloggedin(Calendar.getInstance().getTime());
    	newUser.setRegistered(Calendar.getInstance().getTime());
    	newUser.setPassword(HashUtils.hash(getPassword()));
    	
    	if (avatarData != null) {
    		try {    			
    			FileInputStream in = new FileInputStream(avatarData);
    			ByteArrayOutputStream out = new ByteArrayOutputStream();
    			byte[] a = new byte[8192];
    			int r = -1;
    			while ((r = in.read(a)) != -1) {
    				out.write(a, 0, r);
    			}
    			newUser.setPhoto(out.toByteArray());    			
    			System.out.println("Avatar upload");
    			in.close();
    		} catch(IOException e) {
    			
    		}   		
    	}
    	
    	try {
    		System.out.println(newUser.getUsername() + " " + newUser.getPassword() + " " + newUser.getRegistered().toString() + " " + newUser.getLastloggedin().toString());
        	System.out.println(newUser.getRole().getTitle() + " " + newUser.getStatus().getStatus() + " " + newUser.getSex().toString());
        	System.out.println(newUser.getEmail());
    		entityManager.persist(newUser);    		
    	} catch (EntityExistsException e) {
    		FacesMessages.instance().addToControl("username", "That username is already taken, please choose a different one");
    		return "failed";
    	} catch (InvalidStateException e) {
    		for (InvalidValue invalidValues : e.getInvalidValues()) {
    			System.out.println(invalidValues.toString());
    		}
    	}
    	
    	return "success";
    }   
    
    public String getPassword() {
    	return password;
    }
    public void setPassword(String password) {
    	this.password = password;
    }
    
    public String getConfirm() {
    	return confirm;
    }    
    public void setConfirm(String confirm) {
    	this.confirm = confirm;
    }   
    
    public boolean isConversationStarted() {
    	return conversationStarted;
    }
    public void setConversationStarted(boolean conversationStarted) {
    	this.conversationStarted = conversationStarted;
    }
    
    @Destroy
    @Remove
    public void destroy() {}
}
